#include <string>
#include <vector>
#include <iostream>

#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/exception.hpp>

#include "boost/filesystem/operations.hpp" // includes boost/filesystem/path.hpp
#include "boost/filesystem/fstream.hpp"    // ditto
#include <boost/algorithm/string.hpp>

#include "cfg_callbacks.h"
#include "cfg_parser.h"
#include "rtl_parser.h"

using namespace boost::filesystem;


void process_file(const std::string& path_str)
{
    ifstream file(path_str);
    std::stringstream content;
    content << file.rdbuf();
    //std::cout << content.str();
    std::string line;
    std::string funct_decl = ";; Function";
    int counter = 0;
    boost::regex reg_bb("^<bb (\\d+)>");
    boost::smatch results;

    while (content) {

        getline(content, line);

        if (!line.compare(0, funct_decl.length(), funct_decl)) {
            //std::cout << line <<"\n";
            counter++;
            int pos_fun_decl_begin = funct_decl.length();
            int id_end_pos = line.length() - 2;
            int pos = id_end_pos;
            while (line[pos] != '(') {
                pos--;
            }
            std::string func_id(line, pos + 1, id_end_pos - pos);
            std::string func_name(line, pos_fun_decl_begin, pos - pos_fun_decl_begin-1);
            std::cout << func_id << " " << func_name << "\n";
          //  bool func_end_found = false;
            while (content) {
                getline(content, line);
                 std::cout <<line <<"\n";
                boost::trim(line);
                std::cout <<line <<"\n";
                std::string::const_iterator xItStart = line.begin();
                std::string::const_iterator xItEnd = line.end();
                if (boost::regex_search(xItStart, xItEnd, results, reg_bb)) {
                  //  results[1].begin();
                  results[1].first;
                  std::string str(results[1].first, results[1].second);
                    int number = ::atoi(str.c_str());
                    std::cout << number <<std::endl;
                }
                else if (! line.compare("}")) {
                    break;
                }
            }

        }

    }
    std::cout << counter;
    counter++;

}
/*
    boost::regex reg_ex(";; Function (\\w*) \\((\\w+)\\)");//\\b(?:\\w+?)((\\w)\\2)(?:\\w+?)\\b");  (\\n\\r*)+
    boost::regex reg_ex(";; Function (\\w* )? \\((\\w+)\\)\\n"); //([^\\s]* )*(\\w*)
    boost::regex reg_ex(";; Function .*\\((\\w+)\\)$");// \\(.* )? // ([^\\s]+) \\((\\w+)\\)
    boost::regex reg_ex(".?;; Function (\\s*[\\w_][\\w\\d_:]*\\s*\\s*[\\w_][\\w\\d_:]*\\s*\\(*[,\\w\\s\\*]*\\)*)\\s*\\((\\w+)\\)$");

    boost::smatch results;
    std::cout << "==========================Results============================== \n";
    std::string::const_iterator xItStart = content.str().begin();
    std::string::const_iterator xItEnd = content.str().end();
    while( boost::regex_search(xItStart, xItEnd, results, reg_ex) )
    {
      std::cout << "Word, we've searched, is" << results[0] << "\nFirst " << results[1] <<"_rf" <<"\nSecond " << results[2]<<"\n";
      xItStart = results[0].second;
    }
*/

int main(int argc, char *argv[])
{
    CfgCallbacks event_callbacks;
    //CfgParser  parser(&event_callbacks);
    RtlParser parser;

    boost::filesystem::path dir_path(argv[1], boost::filesystem::native);
    if (!exists(dir_path)) {
        return false;
    }
    directory_iterator end_itr; // default construction yields past-the-end
    for (directory_iterator itr(dir_path);
        itr != end_itr;
        ++itr ) {
        if (is_directory(*itr))
        {
         // if ( find_file( *itr, file_name, path_found ) ) return true;
        }
        else if (std::string::npos != itr->leaf().find(".outof_cfglayout")) { // .cleanup_cfg
            std::cout << itr->leaf() << "\n";
             Context context;
             parser.ParseFile(context, dir_path.string() + "/" + itr->leaf());
             //parser.ParseFile(context, dir_path.string() + "/" + itr->leaf());
            //process_file(dir_path.string() + "/" + itr->leaf());
        //break;
        }
    }

}
